<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<meta http-equiv="X-UA-Compatible" content="ie=edge" />
	<title>Document</title>
	<style type="text/css">
		*{
			margin: 0;
			padding: 0;
		}
		body,html{
			height: 100%;
		}
		#myCanvas{
			padding: 50px;
			
		}
	</style>
</head>
<body>
	<canvas id="myCanvas" width="860" height="800">您的浏览器不支持canvas,请更换浏览器观看！</canvas>
	
	<script type="text/javascript">
		//需求：折线图  柱状图 饼状图 雷达图
	
	function LcCharts (data) {
		if(data.data.length <= 0){
			console.error('数据有误！');
			return;
		}
		const _default = {
			data:[],
			offsetX:50,
			offsetY:50,
			borderColor:'red',
			backgroundColor:'yellow',
			zhexianColor:'blue',
			zhexianShadow:'bluesky',
			unit:unit()
		}
		var options = Object.assign({},_default,data);
		for (var key in options) {
			this.proxy(this,key,options[key]);
		}
		this.getMaxValue();
		this.init();
	}
		
	LcCharts.prototype = {
		constructor:LcCharts,
		init:function(){
//			todo:在这里要考虑距离单位
			this.canvas = document.querySelector(this.el);
			this.canvas.style.backgroundColor = this.backgroundColor;
			if(this.canvas && this.canvas.getContext){
				this.ctx = this.canvas.getContext('2d');
			}
			this.originX = this.offsetX*1;
			this.originY = this.canvas.height*1 - this.offsetY*1;
//			决定了每一个小格的距离大小这个是y轴的，x轴的不需要，直接按照设定的距离单位正常操作即可
			this.dotSpace = Math.ceil(this.maxValue/(this.data.length*1-1));
			this.drawLineBrige();
		},
		proxy:function (obj,key,value) {
			Object.defineProperty(obj,key,{
				configurable:true,
				enumerable:true,
				set:function(newValue){
					if(value === newValue){
						return;
					}
					value = newValue;
				},
				get:function(){
					return value;
				}
			});
		},
		getMaxValue:function () {
			//找见数组中数据最大的值，根据这个值来画图
			var maxValue = 0;
			if(this.data.length <= 0){return;};
			this.unit.each(this.data,function (item) {
				if(item.y*1 > maxValue*1){
					maxValue = item.y;
				}
			})
			this.maxValue = maxValue*1 + 50;
		},
		drawLineBrige:function () {
			var _this = this,
				len = this.data.length,
				_ctx = this.ctx;
			_ctx.font = this.font;
			_ctx.strokeStyle = this.borderColor;
			_ctx.lineWidth = this.lineWidth;
			//绘制y轴
			this.drawLine(this.originX,this.originY,this.originX,this.offsetY);
//			y轴箭头
			_ctx.beginPath();
			_ctx.strokeStyle = this.borderColor;
			_ctx.lineWidth = this.lineWidth;
			_ctx.moveTo(this.originX,this.offsetY);
			_ctx.lineTo(this.originX - 10,this.offsetY + 30);
			_ctx.stroke();
			
			_ctx.save();
			_ctx.beginPath();
			_ctx.font = this.font;
			_ctx.rotate(-90*Math.PI/180);
			_ctx.fillText(this.yText,-60,this.offsetX-10);
			_ctx.restore();
			
			//绘制x轴
			var xXTarget = this.canvas.width - this.originX*2,
				xYTarget = this.originY;
			this.drawLine(this.originX,this.originY,xXTarget,xYTarget);
//			x轴箭头
			_ctx.beginPath();
			_ctx.strokeStyle = this.borderColor;
			_ctx.lineWidth = this.lineWidth;
			_ctx.moveTo(xXTarget,xYTarget);
			_ctx.lineTo(xXTarget - 30,xYTarget + 10);
			_ctx.stroke();
			
			_ctx.save();
			_ctx.beginPath();
			_ctx.font = this.font;
			_ctx.fillText(this.xText,xXTarget - 30,xYTarget + this.offsetY-10);
			_ctx.restore();
			
//			绘制横竖线
			var lineArr = [];
			this.unit.each(this.data,function (item,index) {
//				绘制与x轴平行的线
					var _y = _this.originY - (_this.originY/_this.data.length)*index,
					_x = _this.originX + (xXTarget/_this.data.length)*index;
				_ctx.fillText(_this.dotSpace*index, _this.originX - _this.offsetX, _y, _this.offsetX);
				_this.drawLine(_this.originX,_y,xXTarget,_y);
				//绘制与y轴平行的线
				_ctx.fillText(item.x, _x-_this.offsetY/2, _this.originY+20, _this.offsetY);
				_this.drawLine(_x,_this.originY,_x,_this.offsetY);
//				各种点
				_this.drawArc(_x,_this.originY - (_this.originY*8/9)/_this.maxValue*item.y);
				lineArr.push([_x,_this.originY - (_this.originY*8/9)/_this.maxValue*item.y]);
			});
			lineArr.forEach(function (item,index) {
				if(index < (lineArr.length-1)){
					_this.drawLine(item[0],item[1],lineArr[index*1+1][0],lineArr[index*1+1][1]);
				}
				_ctx.fillText(_this.data[index].y,item[0]+10,item[1]);
			});
			this.drawShadow(lineArr);
		},
		drawArc:function (x,y){
			this.ctx.save();
			this.ctx.beginPath();
			this.ctx.fillStyle = this.borderColor;
			this.ctx.arc(x,y,this.yuanDianR,0,Math.PI*2,false);
			this.ctx.fill();
			this.ctx.restore();
		},
		drawLine:function (x,y,X,Y) {
//			画图
			this.ctx.beginPath();
			this.ctx.moveTo(x,y);
			this.ctx.lineTo(X,Y);
			this.ctx.stroke();
			this.ctx.closePath();
		},
		drawShadow:function (lineArr) {
			var _this = this;
			this.ctx.beginPath();
			this.ctx.moveTo(this.originX,this.originY);
			lineArr.forEach(function (item,index) {
				_this.ctx.lineTo(item[0],item[1]);
				if(index == (lineArr.length-1)){
					_this.ctx.lineTo(item[0],_this.originY);
				}
			});
			this.ctx.closePath();
			var gradient = this.ctx.createLinearGradient(0,0,0,this.originY);
                gradient.addColorStop(0, 'rgba(0,255,0,0.3)');
                gradient.addColorStop(1, 'rgba(0,255,0,0.1)');
			this.ctx.fillStyle = gradient;
			this.ctx.fill();
		}
	}
	
	
	function unit () {
		function each (arr,fn) {
			var i = 0,
				len = arr.length;
			while(i < len){
				if(fn){
					var ret = fn.call(this,arr[i],i);
					if(typeof ret !== "undefined"&&(ret==null||ret==false)) break;
				}
				i++;
			}
		}
		return {
			each:each
		}
	}
	
	
	
	
	new LcCharts({
		el:'#myCanvas',
		data:[
		{x:'2007',y:'750'},
		{x:'2008',y:'425'},
		{x:'2009',y:'800'},
		{x:'2010',y:'700'},
		{x:'2011',y:'800'},
		{x:'2012',y:'675'},
		{x:'2013',y:'375'},
		{x:'2014',y:'775'},
		{x:'2015',y:'2014'} 
	],
	offsetX:30,
	offsetY:30,
	xText:'年份',
	yText:'销量',
	lineWidth:1,
	yuanDianR:5,
	font:'12px Arial'
	});
	
	</script>
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
</body>
</html>